/*
 * Main.cpp
 *
 * Main method for the Cyclometer device.
 *
 * Author: Zachary Masiello
 * Author: Peter-John Rowe
 */

#include "Main.h"

#include <sys/neutrino.h>
#include <hw/inout.h>
#include <sys/mman.h>
#include <stdint.h>
#include <pthread.h>
#include <unistd.h>
#include <cstdlib>
#include <iostream>

int main(int argc, char *argv[])
{
	//Set Up Hardware Input/Output Registers
	if(ThreadCtl(_NTO_TCTL_IO, NULL) == -1)
	{
		perror("Failed to get I/O access permission");
		return 1;
	}
	uintptr_t ctrlHandle;
	ctrlHandle = mmap_device_io(1, 0x28B);
	if(ctrlHandle == MAP_DEVICE_FAILED)
	{
		perror("Failed to map control register");
		return 2;
	}
	out8(ctrlHandle, 0x88);

	//Enable Digital IO Interrupts
	uintptr_t dioiHandle;
	dioiHandle = mmap_device_io(1, 0x284);
	if(dioiHandle == MAP_DEVICE_FAILED)
	{
		perror("Failed to map control register");
		return 2;
	}
	out8(dioiHandle, 0x02);

	//Create DIOInturrupt
	SensorInterrupt* sensorInterrupt = new SensorInterrupt();

	//Create HardwarePorts
	LEDPort* ledPort = new LEDPort();
	AnodePort* anodePort = new AnodePort();
	SegmentPort* segmentPort = new SegmentPort();
	ButtonPort* buttonPort = new ButtonPort();

	//Create Hardware Output Classes
	LEDLight* ledLight = new LEDLight(ledPort);
	LEDDisplay* ledDisplay = new LEDDisplay(segmentPort, anodePort);

	//Create Calculator Class
	Calculator* calculator = new Calculator(sensorInterrupt, ledLight);

	//Create Controller(Cyclometer) Class
	Cyclometer* cyclometer = new Cyclometer(calculator, ledDisplay);

	//Create Hardware Input Class
	ButtonScanner* buttonScanner = new ButtonScanner(buttonPort, cyclometer);

	//Create the Threads
	pthread_t ledLightThread, ledDisplayThread, calculatorThread, buttonScannerThread, sensorInterruptThread;

	//Launch the Threads
	pthread_create(&ledLightThread, NULL, (void*(*)(void*))&LEDLight::run, (void*)ledLight);
	pthread_create(&ledDisplayThread, NULL, (void*(*)(void*))&LEDDisplay::run, (void*)ledDisplay);
	pthread_create(&sensorInterruptThread, NULL, &SensorInterrupt::config, NULL);
	pthread_create(&buttonScannerThread, NULL, (void*(*)(void*))&ButtonScanner::run, (void*)buttonScanner);
	pthread_create(&calculatorThread, NULL, (void*(*)(void*))&Calculator::run, (void*)calculator);

	cyclometer->run();

	return EXIT_SUCCESS;
}

Main::Main()
{
	// TODO Auto-generated constructor stub
}

Main::~Main()
{
	// TODO Auto-generated destructor stub
}
